package com.sum.tea.rongrui.viewmodel

import android.app.Application
import android.util.Log
import androidx.lifecycle.*
import com.example.lib_rongrui.RrReader
import com.rfid.trans.ReaderParameter
import com.sum.tea.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class ScanViewViewModel(application: Application) : AndroidViewModel(application) {

    // LiveData for UI components
    private val _version = MutableLiveData<String>()
    val version: LiveData<String> get() = _version

    private val _result = MutableLiveData<String>()
    val result: LiveData<String> get() = _result

    private val _temp = MutableLiveData<String>()
    val temp: LiveData<String> get() = _temp

    private val _loss = MutableLiveData<String>()
    val loss: LiveData<String> get() = _loss

    // Spinner selections
    val powerSelection = MutableLiveData<Int>()
    val baudRateSelection = MutableLiveData<Int>()
    val bandSelection = MutableLiveData<Int>()
    val maxFrmSelection = MutableLiveData<Int>()
    val minFrmSelection = MutableLiveData<Int>()
    val timeSelection = MutableLiveData<Int>()
    val qValueSelection = MutableLiveData<Int>()
    val sessionSelection = MutableLiveData<Int>()
    val tidAddrSelection = MutableLiveData<Int>()
    val tidLenSelection = MutableLiveData<Int>()
    val dwellSelection = MutableLiveData<Int>()
    val tagFocusSelection = MutableLiveData<Int>()
    val antCheckSelection = MutableLiveData<Int>()
    val profileSelection = MutableLiveData<Int>()
    val rangeSelection = MutableLiveData<Int>()

    // Other variables
    var ReaderType: Int = -1
    var ModuleType: Int = -1
    private var curBand: Int = 0

    // Initialization block
    init {
        // Initialize LiveData with default values if necessary
    }

    // Function to read parameters
    fun readParam() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val param: ReaderParameter = RrReader.rrlib.GetInventoryPatameter()
                withContext(Dispatchers.Main) {
                    tidLenSelection.value = param.Length
                    tidAddrSelection.value = param.WordPtr
                    qValueSelection.value = param.QValue
                    timeSelection.value = param.ScanTime
                    // Assuming spType and spMem correspond to IvtType and Memory
                    // These should be bound to LiveData in the Activity
                    // Similarly for session
                    sessionSelection.value = when (param.Session) {
                        255 -> 4
                        254 -> 5
                        253 -> 6
                        252 -> 7
                        251 -> 8
                        else -> param.Session
                    }
                }

                if (RrReader.rrlib.ModuleType == 2) {
                    val data = ByteArray(30)
                    val len = IntArray(1)
                    val fCmdRet = RrReader.rrlib.GetCfgParameter(7, data, len)
                    if (fCmdRet == 0 && len[0] == 3) {
                        withContext(Dispatchers.Main) {
                            timeSelection.value = data[0].toInt()
                            dwellSelection.value = (data[1] - 2).toInt()
                        }
                    }
                }

                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.get_success))
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.get_failed))
                }
                Log.e("ScanViewViewModel", "Error in readParam", e)
            }
        }
    }

    // Function to read information
    fun readInformation() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val Version = ByteArray(2)
                val Power = ByteArray(1)
                val band = ByteArray(1)
                val MaxFre = ByteArray(1)
                val MinFre = ByteArray(1)
                val result = RrReader.rrlib.GetReaderInformation(Version, Power, band, MaxFre, MinFre)
                if (result == 0) {
                    val hvn = (Version[0].toInt() and 0xFF).toString().padStart(2, '0')
                    val lvn = (Version[1].toInt() and 0xFF).toString().padStart(2, '0')
                    ReaderType = RrReader.rrlib.GetReaderType()
                    val ModuleInfo = if (ReaderType == 0x70 || ReaderType == 0x71 || ReaderType == 0x31) {
                        val Describe = ByteArray(16)
                        val descResult = RrReader.rrlib.GetModuleDescribe(Describe)
                        var dscInfo = ""
                        when (Describe[0].toInt()) {
                            0x00 -> dscInfo = "S"
                            0x01 -> dscInfo = "Plus"
                            0x02 -> dscInfo = "Pro"
                            else -> dscInfo = "Unknown"
                        }
                        "$hvn.$lvn (${Integer.toHexString(ReaderType)}-$dscInfo)"
                    } else {
                        "$hvn.$lvn (${Integer.toHexString(ReaderType)})"
                    }

                    withContext(Dispatchers.Main) {
                        _version.value = ModuleInfo
                        powerSelection.value = Power[0].toInt()
                        curBand = band[0].toInt()
                        setFre(band[0].toInt())
                        var bandIndex = band[0].toInt()
                        bandIndex = when (bandIndex) {
                            8 -> bandIndex - 4
                            0 -> 5
                            else -> bandIndex - 1
                        }
                        bandSelection.value = bandIndex
                        minFrmSelection.value = MinFre[0].toInt()
                        maxFrmSelection.value = MaxFre[0].toInt()
                        writeLog(getApplication<Application>().getString(R.string.get_success))
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        writeLog(getApplication<Application>().getString(R.string.get_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.get_failed))
                }
                Log.e("ScanViewViewModel", "Error in readInformation", e)
            }
        }
    }

    // Function to read focus
    fun readFocus() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val data = ByteArray(250)
                val len = IntArray(1)
                val fCmdRet = RrReader.rrlib.GetCfgParameter(8, data, len)
                if (fCmdRet == 0 && len[0] == 1) {
                    withContext(Dispatchers.Main) {
                        tagFocusSelection.value = data[0].toInt()
                        writeLog(getApplication<Application>().getString(R.string.get_success))
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        writeLog(getApplication<Application>().getString(R.string.get_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.get_failed))
                }
                Log.e("ScanViewViewModel", "Error in readFocus", e)
            }
        }
    }

    // Function to read antenna check
    fun readCheckAnt() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val AntCheck = ByteArray(1)
                val fCmdRet = RrReader.rrlib.GetCheckAnt(AntCheck)
                if (fCmdRet == 0) {
                    withContext(Dispatchers.Main) {
                        antCheckSelection.value = AntCheck[0].toInt()
                        writeLog(getApplication<Application>().getString(R.string.get_success))
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        writeLog(getApplication<Application>().getString(R.string.get_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.get_failed))
                }
                Log.e("ScanViewViewModel", "Error in readCheckAnt", e)
            }
        }
    }

    // 在 ScanViewViewModel.kt 中添加以下方法

    fun setRange(index: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                // 创建数据数组，前三个字节为0，第四个字节为选中的索引值
                val data = byteArrayOf(0x00, 0x00, 0x00, index.toByte())
                val len = 4

                // 调用 SetCfgParameter 方法设置范围参数
                val fCmdRet = RrReader.rrlib.SetCfgParameter(0.toByte(), 16.toByte(), data, len)

                // 切换到主线程更新UI
                withContext(Dispatchers.Main) {
                    if (fCmdRet == 0) {
                        writeLog(getApplication<Application>().getString(R.string.set_success))
                    } else {
                        writeLog(getApplication<Application>().getString(R.string.set_failed))
                    }
                }
            } catch (e: Exception) {
                // 处理异常并更新UI
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_failed))
                }
                Log.e("ScanViewViewModel", "Error in setRange", e)
            }
        }
    }

    // 确保在 ViewModel 中有一个写日志的方法
    private fun writeLog(message: String) {
        _result.postValue(message)
    }


    // Function to get range control
    fun getRangeControl() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val data = ByteArray(250)
                val len = IntArray(1)
                val fCmdRet = RrReader.rrlib.GetCfgParameter(16, data, len)
                if (fCmdRet == 0 && len[0] == 4) {
                    withContext(Dispatchers.Main) {
                        rangeSelection.value = (data[3].toInt() and 0xFF)
                        writeLog(getApplication<Application>().getString(R.string.get_success))
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        writeLog(getApplication<Application>().getString(R.string.get_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.get_failed))
                }
                Log.e("ScanViewViewModel", "Error in getRangeControl", e)
            }
        }
    }

    // Function to read profile
    fun readProfile() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val Profile = ByteArray(1)
                val result = RrReader.rrlib.GetProfile(Profile)
                if (result == 0) {
                    val index = if (ModuleType == 2) {
                        when (Profile[0].toInt() and 0xFF) {
                            11 -> 0
                            1 -> 1
                            15 -> 2
                            12 -> 3
                            3 -> 4
                            5 -> 5
                            7 -> 6
                            13 -> 7
                            50 -> 8
                            51 -> 9
                            52 -> 10
                            53 -> 11
                            else -> 0
                        }
                    } else if (ModuleType == 3) {
                        (Profile[0].toInt() and 0xFF) - 0x10
                    } else {
                        Profile[0].toInt() and 0xFF
                    }
                    withContext(Dispatchers.Main) {
                        profileSelection.value = index
                        writeLog(getApplication<Application>().getString(R.string.set_success))
                    }
                } else if (ModuleType == 3) {
                    withContext(Dispatchers.Main) {
                        profileSelection.value = (Profile[0].toInt() and 0xFF) - 0x10
                        writeLog(getApplication<Application>().getString(R.string.set_failed))
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        writeLog(getApplication<Application>().getString(R.string.set_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_failed))
                }
                Log.e("ScanViewViewModel", "Error in readProfile", e)
            }
        }
    }

    // Function to set frequency based on band
    fun setFre(m: Int) {
        viewModelScope.launch(Dispatchers.Main) {
            // This function mainly updates the spinner selections which are handled via LiveData
            // You may need to update LiveData or handle UI directly in Activity
        }
        // The original Java method populates spinners based on 'm'
        // This logic can be handled in the Activity using LiveData observers
    }

    // Function to set parameters
    fun setParam(
        length: Int,
        wordPtr: Int,
        qValue: Int,
        scanTime: Int,
        ivtType: Int,
        memory: Int,
        session: Int
    ) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val param = RrReader.rrlib.GetInventoryPatameter()
                param.Length = length
                param.WordPtr = wordPtr
                param.QValue = qValue
                param.ScanTime = scanTime
                param.IvtType = ivtType
                param.Memory = memory
                param.Session = when (session) {
                    4 -> 255
                    5 -> 254
                    6 -> 253
                    7 -> 252
                    8 -> 251
                    else -> session
                }
                param.Interval = 0
                RrReader.rrlib.SetInventoryPatameter(param)

                if (RrReader.rrlib.ModuleType == 2) {
                    // Additional configuration for ModuleType 2
                    // This should be passed as parameters to the function
                    // Assuming jgTimes and dwell are provided
                }

                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_success))
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_failed))
                }
                Log.e("ScanViewViewModel", "Error in setParam", e)
            }
        }
    }

    // Function to set RF Power and Region
    fun setRfPowerAndRegion(power: Int, band: Int, maxFre: Int, minFre: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            var temp = ""
            try {
                val powerResult = RrReader.rrlib.SetRfPower(power.toByte())
                if (powerResult != 0) {
                    temp = getApplication<Application>().getString(R.string.power_error)
                }

                val regionResult = RrReader.rrlib.SetRegion(band.toByte(), maxFre.toByte(), minFre.toByte())
                if (regionResult != 0) {
                    temp = if (temp.isEmpty()) {
                        getApplication<Application>().getString(R.string.frequent_error)
                    } else {
                        "$temp,\r\n${getApplication<Application>().getString(R.string.frequent_error)}"
                    }
                }

                withContext(Dispatchers.Main) {
                    if (temp.isNotEmpty()) {
                        writeLog(temp)
                    } else {
                        writeLog(getApplication<Application>().getString(R.string.set_success))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_failed))
                }
                Log.e("ScanViewViewModel", "Error in setRfPowerAndRegion", e)
            }
        }
    }

    // Function to set baud rate
    fun setBaudRate(baudRate: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val result = RrReader.rrlib.SetBaudRate(baudRate)
                withContext(Dispatchers.Main) {
                    if (result == 0) {
                        writeLog(getApplication<Application>().getString(R.string.set_success))
                    } else {
                        writeLog(getApplication<Application>().getString(R.string.set_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_failed))
                }
                Log.e("ScanViewViewModel", "Error in setBaudRate", e)
            }
        }
    }

    // Function to set antenna check
    fun setAntCheck(antCheck: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val fCmdRet = RrReader.rrlib.SetCheckAnt(antCheck.toByte())
                withContext(Dispatchers.Main) {
                    if (fCmdRet == 0) {
                        writeLog(getApplication<Application>().getString(R.string.set_success))
                    } else {
                        writeLog(getApplication<Application>().getString(R.string.set_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_failed))
                }
                Log.e("ScanViewViewModel", "Error in setAntCheck", e)
            }
        }
    }

    // Function to set focus
    fun setFocus(index: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val data = byteArrayOf(index.toByte())
                val len = 1
                val fCmdRet = RrReader.rrlib.SetCfgParameter(0, 8, data, len)
                withContext(Dispatchers.Main) {
                    if (fCmdRet == 0) {
                        writeLog(getApplication<Application>().getString(R.string.set_success))
                    } else {
                        writeLog(getApplication<Application>().getString(R.string.set_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_failed))
                }
                Log.e("ScanViewViewModel", "Error in setFocus", e)
            }
        }
    }

    // Function to set profile
    fun setProfile(index: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val profile = if (ModuleType == 2) {
                    when (index) {
                        0 -> 11
                        1 -> 1
                        2 -> 15
                        3 -> 12
                        4 -> 3
                        5 -> 5
                        6 -> 7
                        7 -> 13
                        8 -> 50
                        9 -> 51
                        10 -> 52
                        11 -> 53
                        else -> 5
                    }
                } else {
                    index
                }
                val result = RrReader.rrlib.SetProfile(profile.toByte())
                withContext(Dispatchers.Main) {
                    if (result == 0) {
                        writeLog(getApplication<Application>().getString(R.string.set_success))
                    } else {
                        writeLog(getApplication<Application>().getString(R.string.set_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.set_failed))
                }
                Log.e("ScanViewViewModel", "Error in setProfile", e)
            }
        }
    }

    // Function to measure loss
    fun measureLoss() {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val Freq = ByteArray(4)
                val loss = ByteArray(1)
                if (curBand == 4) {
                    Freq[0] = 0x00
                    Freq[1] = 0x0D
                    Freq[2] = 0x33
                    Freq[3] = 0x4C
                } else {
                    Freq[0] = 0x00
                    Freq[1] = 0x0D
                    Freq[2] = 0xF7.toByte()
                    Freq[3] = 0x32
                }

                val fCmdRet = RrReader.rrlib.MeasureReturnLoss(Freq, 0x00.toByte(), loss)
                if (fCmdRet == 0) {
                    withContext(Dispatchers.Main) {
                        _loss.value = loss[0].toString()
                        writeLog(getApplication<Application>().getString(R.string.get_success))
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        writeLog(getApplication<Application>().getString(R.string.get_failed))
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    writeLog(getApplication<Application>().getString(R.string.get_failed))
                }
                Log.e("ScanViewViewModel", "Error in measureLoss", e)
            }
        }
    }

    // Function to read temperature
    fun readTemperature() {
        // Implement similar to other read functions if applicable
    }

}
